﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Stone
{
    //class GPRMC
    //{
    //    public static CultureInfo NmeaCultureInfo = new CultureInfo("en-US");
    //    public static double MPHPerKnot = double.Parse("1.150779", NmeaCultureInfo);

    //    //$GPRMC,154005.138,V,4529.4440,N,00914.2673,E,014.5,330.0,230810,,,N*73
    //    // http://maps.google.com/maps?sll=42.293564,-81.738281&sspn=22.467179,56.90918&ie=UTF8&ll=41.869561,-81.738281&spn=23.422498,56.90918&t=h&z=5
    //    public double Latitudine = 0;
    //    public string Latitudine_NordSud = "N";
    //    public double Longitudine = 0;
    //    public string Longitudine_EstOvest = "E";
    //    public DateTime SatelliteTime;
    //    public double Velocita = 0;
    //    public double Direzione = 0;
    //    public bool PosizioneOttenuta = false;

    //    public void Parsa(string frase)
    //    {
    //        string[] Words = frase.Split(',');

    //        if (Words[3] != "" & Words[4] != "" & Words[5] != "" & Words[6] != "")
    //        {
    //            Latitudine = double.Parse(Words[3], NmeaCultureInfo);
    //            Longitudine = double.Parse(Words[5], NmeaCultureInfo);
    //        }

    //        if (Words[1] != "")
    //        {
    //            int UtcHours = Convert.ToInt32(Words[1].Substring(0, 2));
    //            int UtcMinutes = Convert.ToInt32(Words[1].Substring(2, 2));
    //            int UtcSeconds = Convert.ToInt32(Words[1].Substring(4, 2));
    //            int UtcMilliseconds = 0;

    //            if (Words[1].Length > 7)
    //                UtcMilliseconds = Convert.ToInt32(Words[1].Substring(7));

    //            System.DateTime Today = System.DateTime.Now.ToUniversalTime();
    //            SatelliteTime = new System.DateTime(Today.Year, Today.Month, Today.Day, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds);
    //        }

    //        if (Words[7] != "")
    //        {
    //            Velocita = double.Parse(Words[7], NmeaCultureInfo) * MPHPerKnot;
    //        }

    //        if (Words[8] != "")
    //        {
    //            Direzione = double.Parse(Words[8], NmeaCultureInfo);
    //        }

    //        if (Words[2] != "")
    //        {
    //            switch (Words[2])
    //            {
    //                case "A":
    //                    PosizioneOttenuta = true;
    //                    break;
    //                case "V":
    //                    PosizioneOttenuta = false;
    //                    break;
    //            }
    //        }

    //    }
    //}


    /// <summary>
    /// Recommended minimum specific GPS/Transit data
    /// </summary>
    public class GPRMC
    {
        public string NMEA_string = ""; 
        /// <summary>
        /// Enum for the Receiver Status information.
        /// </summary>
        public enum StatusEnum
        {
            /// <summary>
            /// Fix warning
            /// </summary>
            Warning,
            /// <summary>
            /// Fix OK
            /// </summary>
            OK,
            /// <summary>
            /// Bad fix
            /// </summary>
            BadFix,
            /// <summary>
            /// GPS fix
            /// </summary>
            GPS,
            /// <summary>
            /// Differential GPS fix
            /// </summary>
            DGPS
        }

        /// <summary>
        /// Initializes the NMEA Recommended minimum specific GPS/Transit data
        /// </summary>
        public GPRMC()
        {
            _position = new Coordinate();
        }

        /// <summary>
        /// Initializes the NMEA Recommended minimum specific GPS/Transit data and parses an NMEA sentence
        /// </summary>
        /// <param name="NMEAsentence"></param>
        public GPRMC(string NMEAsentence)
        {
            NMEA_string = NMEAsentence;

            try
            {
                //Split into an array of strings.
                string[] split = NMEAsentence.Split(new Char[] { ',' });

                //Extract date/time
                try
                {
                    string[] DateTimeFormats = { "ddMMyyHHmmss", "ddMMyy", "ddMMyyHHmmss.FFFFFF" };
                    if (split[9].Length >= 6)
                    { //Require at least the date to be present 
                        string time = split[9] + split[1]; // +" 0";
                        _timeOfFix = DateTime.ParseExact(time, DateTimeFormats, GlobalFunctions.numberFormat_EnUS, System.Globalization.DateTimeStyles.AssumeUniversal);
                    }
                    else
                        _timeOfFix = new DateTime();
                }
                catch { _timeOfFix = new DateTime(); }

                if (split[2] == "A")
                    _status = StatusEnum.OK;
                else
                    _status = StatusEnum.Warning;

                _position = new Coordinate(GlobalFunctions.GPSToDecimalDegrees(split[5], split[6]), GlobalFunctions.GPSToDecimalDegrees(split[3], split[4]));

                GlobalFunctions.dblTryParse(split[7], out _speed);
                GlobalFunctions.dblTryParse(split[8], out _course);
                GlobalFunctions.dblTryParse(split[10], out _magneticVariation);
            }
            catch { }
        }

        #region Properties

        private Coordinate _position;
        private StatusEnum _status;
        private DateTime _timeOfFix;
        private double _speed;
        private double _course;
        private double _magneticVariation;
        //private string _magneticVariationDirection;

        /// <summary>
        /// Indicates the current status of the GPS receiver.
        /// </summary>
        public StatusEnum Status
        {
            get { return _status; }
            //set { _status = value; }
        }

        /// <summary>
        /// Coordinate of recieved position
        /// </summary>
        public Coordinate Position
        {
            get { return _position; }
            //set { _position = value; }
        }

        /// <summary>
        /// Groundspeed in knots.
        /// </summary>
        public double Speed
        {
            get { return _speed; }
            //set { _speed = value; }
        }

        /// <summary>
        /// Course (true, not magnetic) in decimal degrees.
        /// </summary>
        public double Course
        {
            get { return _course; }
            //set { _course = value; }
        }

        /// <summary>
        /// MagneticVariation in decimal degrees.
        /// </summary>
        public double MagneticVariation
        {
            get { return _magneticVariation; }
            //set { _magneticVariation = value; }
        }

        ///// <summary>
        ///// The direction of the magnetic variation.
        ///// </summary>
        //public string MagneticVariationDirection
        //{
        //    get { return _magneticVariationDirection; }
        //    //set { _magneticVariationDirections = value; }
        //}

        /// <summary>
        /// Date and Time of fix - Greenwich mean time.
        /// </summary>
        public DateTime TimeOfFix
        {
            get { return _timeOfFix; }
            //set { _timeOfFix = value; }
        }
        #endregion

    }

}
